/*
* Copyright 2010 Pavel Kozhin 
*
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed  under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License.
*
* Author: Pavel Kozhin.
*/

package org.etherframework.behaviour
{
	import flash.events.Event;
	import flash.events.IEventDispatcher;
	import flash.utils.Dictionary;
	
	import org.etherframework.behaviour.rules.IRules;
	import org.etherframework.core.Access;
	import org.etherframework.core.DomainAccess;
	import org.etherframework.core.IBridge;
	import org.etherframework.core.events.InteractionEvent;
	import org.etherframework.core.util.ListenerUtil;
	
	internal final class BehaviourDispatcher implements IEventDispatcher
	{
		private var owner:IRules;
		
		private var access:String;
		
		private var domain:String;
		
		private var bridge:IBridge;
		
		private var listeners:ListenerUtil;
		
		public function BehaviourDispatcher(owner:IRules, bridge:IBridge, access:String, domain:String)
		{
			this.owner = owner;
			this.bridge = bridge;
			this.access = access;
			this.domain = domain;
			listeners = new ListenerUtil(new Dictionary());
		}
		
		public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, 
										 priority:int = 0, useWeakReference:Boolean = false):void
		{
			bridge.listen(InteractionEvent.EVENT + type, listener, 
				access, domain, useCapture, priority, useWeakReference);
			
			if (access == Access.HIERARCHICAL)
			{
				var handler:Function = function(event:Event):void
				{
					if ((domain == DomainAccess.MULTIPLE) || 
						((domain == DomainAccess.SINGLE) && (event.target.loaderInfo) &&
						(event.target.loaderInfo.applicationDomain == bridge.host.loaderInfo.applicationDomain)))
					{
						listener(event);
					}
				};
				listeners.addListener(type, bridge.host, handler, useCapture, priority);
			}
		}
		
		public function removeEventListener(type:String, listener:Function, useCapture:Boolean = false):void
		{
			bridge.unlisten(InteractionEvent.EVENT + type, listener, access, domain, useCapture);
		}
		
		public function dispatchEvent(event:Event):Boolean
		{
			if (!event)
				return false;
			
			if (event.bubbles)
			{
				return bridge.host.dispatchEvent(event);
			}
			
			var evt:InteractionEvent = new InteractionEvent(InteractionEvent.EVENT + event.type);
			evt.initiator = owner;
			evt.data = event;
			
			return bridge.dispatch(evt, access, domain);
		}
		
		public function hasEventListener(type:String):Boolean
		{
			return false;
		}
		
		public function willTrigger(type:String):Boolean
		{
			return false;
		}
		
		public function removeAllEventListeners():void
		{
			listeners.removeListeners();
		}
		
	}
}